package com.zeny.express.framework.shared.util;

import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 日期工具类，扩展apache日期类
 * 
 * @author zhuwei
 * @date 2013年10月30日 下午5:22:25
 */
public class DateUtils extends org.apache.commons.lang.time.DateUtils {

	private static final Log logger = LogFactory.getLog(DateUtils.class);

	public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";

	public static final String ISO_DATETIME_FORMAT = "yyyy-MM-dd'T'HH:mm:ss";

	public static final String TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss.S";

	public static final String DATE_FORMAT = "yyyy-MM-dd";

	public static final String TIME_FORMAT = "HH:mm:ss";

	public static final String DAYTIME_START = "00:00:00";

	public static final String DAYTIME_END = "23:59:59";

	private static final String[] FORMATS = { DATETIME_FORMAT,
			ISO_DATETIME_FORMAT, TIMESTAMP_FORMAT, DATE_FORMAT,
			"yyyy-MM-dd HH:mm", TIME_FORMAT };

	/**
	 * 获取精确到妙的当前时间
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:35:20
	 * @return
	 */
	public static Date currentSeconds() {
		return DateUtils.truncate(Calendar.getInstance().getTime(),
				Calendar.MILLISECOND);
	}

	/**
	 * 字符串转为日期
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:23:24
	 * @param str
	 * @return
	 */
	public static Date parseDate(String str) {
		
		if (StringUtils.isEmpty(str)) {
			return null;
		}
		
		try {
			return org.apache.commons.lang.time.DateUtils.parseDate(str,
					FORMATS);
		} catch (ParseException e) {
			logger.error(e.getMessage(), e);
			return null;
		}
	}

	/**
	 * 字符串转为日期
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:23:24
	 * @param str
	 * @return
	 */
	public static Date parseDate(String str, String format) {

		if (StringUtils.isEmpty(str)) {
			return null;
		}
		
		try {
			return org.apache.commons.lang.time.DateUtils.parseDate(str,
					new String[] { format });
		} catch (ParseException e) {
			logger.error(e.getMessage(), e);
			return null;
		}
	}

	/**
	 * 日期转为字符串
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:23:39
	 * @param date
	 * @return
	 */
	public static String format(Date date) {

		if (date == null) {
			return null;
		}

		return org.apache.commons.lang.time.DateFormatUtils.format(date,
				DATETIME_FORMAT);
	}

	/**
	 * 日期转为字符串
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:26:10
	 * @param date
	 * @param format
	 * @return
	 */
	public static String format(Date date, String format) {
		if (date == null) {
			return null;
		}

		if (format == null) {
			format = DATETIME_FORMAT;
		}

		return org.apache.commons.lang.time.DateFormatUtils.format(date,
				format);
	}

	/**
	 * 日期转为字符串
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:23:39
	 * @param date
	 * @return
	 */
	public static String format(long millis) {

		return org.apache.commons.lang.time.DateFormatUtils.format(millis,
				DATETIME_FORMAT);
	}

	/**
	 * 日期转为字符串
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:23:39
	 * @param date
	 * @return
	 */
	public static String format(long millis, String format) {

		if (format == null) {
			format = DATETIME_FORMAT;
		}

		return org.apache.commons.lang.time.DateFormatUtils.format(millis,
				format);
	}

	/**
	 * 返回该天从00:00:00开始的日期
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:30:11
	 * @param date
	 * @param diffDays
	 * @return
	 */
	public static Date getStartDatetime(Date date) {
		if (date == null) {
			return null;
		}

		return DateUtils.truncate(date, Calendar.DATE);

	}

	/**
	 * 返回N天后从00:00:00开始的日期
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:30:11
	 * @param date
	 * @param diffDays
	 * @return
	 */
	public static Date getStartDatetime(Date date, Integer diffDays) {

		return DateUtils.addSeconds(DateUtils.addDays(
				DateUtils.truncate(date, Calendar.DATE), diffDays + 1), -1);
	}

	/**
	 * 返回该天到23:59:59结束的日期
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:30:02
	 * @param date
	 * @return
	 */
	public static Date getEndDatetime(Date date) {
		if (date == null) {
			return null;
		}

		return DateUtils.addSeconds(
				DateUtils.addDays(DateUtils.truncate(date, Calendar.DATE), 1),
				-1);
	}

	/**
	 * 返回N天到23:59:59结束的日期
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:29:48
	 * @param date
	 * @param diffDays
	 * @return
	 */
	public static Date getEndDatetime(Date date, Integer diffDays) {
		if (date == null) {
			return null;
		}

		return DateUtils.addSeconds(DateUtils.addDays(
				DateUtils.truncate(date, Calendar.DATE), diffDays + 1), -1);
	}

	/**
	 * 返回该日期的最后一刻，精确到纳秒
	 * 
	 * @author zhuwei
	 * @date 2013年10月30日 下午5:29:38
	 * @param endTime
	 * @return
	 */
	public static Timestamp getLastEndDatetime(Date endTime) {
		Timestamp ts = new Timestamp(endTime.getTime());
		ts.setNanos(999999999);
		return ts;
	}

	/**
	 * 返回两个时间的相差天数
	 * 
	 * @param startTime
	 *            对比的开始时间
	 * @param endTime
	 *            对比的结束时间
	 * @return 相差天数
	 */
	public static Long getTimeDiff(String startTime, String endTime) {
		Long days = null;
		Date startDate = null;
		Date endDate = null;
		try {
			if (startTime.length() == 10 && endTime.length() == 10) {
				startDate = new SimpleDateFormat(DATE_FORMAT).parse(startTime);
				endDate = new SimpleDateFormat(DATE_FORMAT).parse(endTime);
			} else {
				startDate = new SimpleDateFormat(DATETIME_FORMAT)
						.parse(startTime);
				endDate = new SimpleDateFormat(DATETIME_FORMAT).parse(endTime);
			}

			Calendar c = Calendar.getInstance();
			c.setTime(startDate);
			long l_s = c.getTimeInMillis();
			c.setTime(endDate);
			long l_e = c.getTimeInMillis();
			days = (l_e - l_s) / 86400000;
		} catch (ParseException e) {
			if (logger.isWarnEnabled()) {
				logger.warn(e.getMessage());
			}
			days = null;
		}
		return days;
	}

}
